/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package battleshipgame.ui;
import battleshipgame.manager.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import battleshipgame.logic.*;
import battleshipgame.logic.Board.SquareStatus;
import java.util.ArrayList;

public class ConsoleIOManager {

    public static enum UserInputType {NONE,
                                                                       MANUAL_INPUT, XML_INPUT,
                                                                       MARK_PLAYER, MARK_SQUARE, CANCEL_MARK_SQUARE, BOMB_SQUARE};
    /* @shaked
     * inits the game with value from  xml file or from the user
     * TODO: handle invalid XML handle invalid user input
   */


    //TODO: input tests: invalid xml, invalid data, char\string instead of number etc.

    protected static int inputInt(String message) throws ExitSignalException
    {
        boolean inputEnterdOK = false;
        int parsedInt= -1;
        while(!inputEnterdOK)
        {
            try
            {
                parsedInt = Integer.parseInt(input(message));
                inputEnterdOK=true;
                
            }
            catch(NumberFormatException e)
            {
                System.out.println("!!!Invalid number input!!!");
            }
            catch(InvalidInputException e)
            {
                System.out.println("!!!Invalid intput!!!");
            }
        }
        return parsedInt;
    }

    /*
     * @shaked receives game type
     */
    public static UserInputType showWelcomeScreen() throws ExitSignalException
    {
        UserInputType[] userInputTypesAllow= {UserInputType.XML_INPUT, UserInputType.MANUAL_INPUT};
        return hanleUserInput( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
               + "Welcome to Battleship game by Eliran and Shaked\n"
               + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
               + "1.\tread automatically from file.\n"
               + "2.\tread manualy.\n"
               + "press q to exit\n"
               + "enter yout choice:", userInputTypesAllow);
        }

    /*
     * @shaked receives from current player which player to attack. returns
     */
    public static Player getPlayerToAttack(Player currentPlayer, ArrayList<Player> players) throws ExitSignalException
    {
        String userInput = "";
        Player selectedPlayer = null;
        UserInputType userInputType = UserInputType.NONE;
        
        
        try
        {
            //System.out.println("Hello " + player.getName() + ".\n" + "select  player to attack:");
            System.out.println("select  player to attack:");
             System.out.println(" List of opponents:");
             for(int i=0; i< players.size(); i++)
             {
                 if (!(players.get(i).equals(currentPlayer)))
                 {
                     System.out.println("\t Player #" + players.get(i).getId()  +"\t" + players.get(i).getName());
                 }
             }
            int userInputIndex  = inputInt("Enter number for Player to Attack:");
            if(userInputIndex >= players.size() || players.get(userInputIndex).equals(currentPlayer))
            {
                System.out.println("!!!Invalid Player selected!!!");
                return getPlayerToAttack(currentPlayer, players);
            }
            for(int i=0; i< players.size(); i++)
            {
                if(players.get(i).getId() == userInputIndex && (!(players.get(i).equals(currentPlayer))) )
                {
                    selectedPlayer = players.get(i);
                }
            }
            if(selectedPlayer == null)
            {
                throw new InvalidInputException("invalid user # selected");
            }
            
        }
        catch (InvalidInputException e)
        {
            System.out.println("Invalid input inserted.\t " + e.getMessage());
        }
        return selectedPlayer;

        }

    public static UserInputType getCommandFromUser() throws ExitSignalException
    {
        UserInputType[] userInputTypesAllow= {UserInputType.MARK_SQUARE, UserInputType.CANCEL_MARK_SQUARE, UserInputType.BOMB_SQUARE};
        return hanleUserInput( "What would you like to do?\n"
               + "1.\tMark Square\n"
               + "2.\tCancel mark of Square.\n"
               + "3.\tBomb Square\n"
               + "enter yout choice:", userInputTypesAllow);
    }
    
    public static String getCoordianteFromUser() throws ExitSignalException
    {
        String Coordinate = null;
        try
        {
            Coordinate= input("please Enter Coordiante:");
        }
        catch(InvalidInputException e)
        {
            System.out.println("Invalid input " + e.getMessage());
        }
        return Coordinate;
    }


    /*
     * @shaked
     * inputString - string to print to user
     * userInputTypesAllow - list of input allow to receive fomr user
     */
     private static UserInputType hanleUserInput(String inputString, UserInputType[] userInputTypesAllow) throws ExitSignalException
    {
        String userInput = "";
        UserInputType userInputType = UserInputType.NONE;
        try
        {      
            int userInputIndex  = inputInt(inputString);

            if (userInputIndex > userInputTypesAllow.length || userInputIndex<=0)
            {
                    throw new InvalidInputException("Invalid selection");
            }
            else
            {
                // plus one to match ui input to array
                //System.out.println(userInputIndex);
                userInputType = userInputTypesAllow[userInputIndex-1];
            }
        }
        catch (InvalidInputException e)
        {
            System.out.println("Invalid input inserted.\t " + e.getMessage());
        }
        return userInputType;

        }

//@shaked simple input output method
    protected static  String input(String str)  throws InvalidInputException, ExitSignalException
    {
        System.out.print(str);
        // Defines the standard input stream
       BufferedReader stdin = new BufferedReader
        (new InputStreamReader(System.in));
        String userInput; // Creates a varible called message for input
        try
        {
            userInput = stdin.readLine();
        }
        catch(IOException e)
        {
           throw new InvalidInputException(e.getMessage());
        }
        if (userInput.equals("Q") || userInput.equals("q"))
        {
            throw new ExitSignalException();
        }
        return userInput;

    }

    /*
     @shaked
     * prints a board with the marks matrix
     */
    public static void printBoard(String playerName, Board board, MarkMatrix markmatrix)
    {
        System.out.println("board of "  + playerName + ":");
        //TODO print outer lines of the board 1 2 3 4... a b c d

        for (char y = '1' ; y<= '9'+1; y++)
        {
            // print lines
            printLineSeperator();

            System.out.print("  |  ");
            for (char x = 'A' ; x<= 'J'; x++)
            {
                String coordiante;
                if(y != '9' + 1)
                {
                    coordiante = x + "" + y;
                }
                else
                {
                    coordiante = x + "10";
                }

                //TODO delete me
                //System.out.println(coordiante);
                
                try{
                    SquareStatus squareStatus = board.getSquareStatusByCoordinate(coordiante);
                    //TODO delte debug

                    char charToPrint = ' ';
                    switch(squareStatus)
                    {
                        case BOMBED_SEA:
                            charToPrint = 'O';
                            break;
                        case BOMBED_BATTLESHIP:
                            charToPrint = 'X';
                            break;
                        case SEA:
                        case BATTLESHIP:
                            if(markmatrix.IsMarked(coordiante))
                            {
                                charToPrint = 'M';
                            }
                            else
                            {
                                charToPrint = 'S';
                            }
                            break;
                    }
                    System.out.print(charToPrint);
                    System.out.print("  |  ");
                }
                catch(InvalidInputException e)
                {
                    //TODO delete debug
                    System.out.println(e.toString());
                }
            }
            System.out.println();
        }
        
         printLineSeperator();

        System.out.println();
    }


    private static void printLineSeperator()
    {
        System.out.print(" ");
         for (char y = '1' ; y<= '9'+5; y++)
         {
             System.out.print(" -- ");
         }
         System.out.println();
    }
    public static void declarCurrentPlayer(String name) {
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        System.out.println("Current turn belongs to : " + name);
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    }

    public static void declareBombedABattleship()
    {
        System.out.println("!!!!!!You bombed a Battleship!!!!!!");
    }

    public static void declareWinner(String playerName)
    {
        System.out.println("############################");
        System.out.println(playerName +  " has won the game!!!" );
        System.out.println("############################");
    }

    public static void printExitMessage() {
        System.out.println("Exiting...");
    }
    

    public static void printException(Exception e) {
        System.out.println("~~~~~~~~~~~~~~~ERROR~~~~~~~~~~~~~~~~~");
        System.out.println(e.getMessage());
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    }

}
